package com.ncst.backend.util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Random;

/**
 * 验证码工具类
 * 用于生成图形验证码
 */
public class CaptchaUtil {
    
    // 验证码字符源
    private static final String CAPTCHA_CHARS = "ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
    
    // 验证码长度
    private static final int CAPTCHA_LENGTH = 4;
    
    // 图片宽度
    private static final int IMAGE_WIDTH = 100;
    
    // 图片高度
    private static final int IMAGE_HEIGHT = 40;
    
    // 干扰线数量
    private static final int INTERFERENCE_LINE_COUNT = 5;
    
    // 噪点数量
    private static final int NOISE_POINT_COUNT = 50;

    /**
     * 生成验证码文本
     * @return 4位随机验证码字符串
     */
    public static String generateCaptchaText() {
        Random random = new Random();
        StringBuilder captcha = new StringBuilder();

        for (int i = 0; i < CAPTCHA_LENGTH; i++) {
            int index = random.nextInt(CAPTCHA_CHARS.length());
            captcha.append(CAPTCHA_CHARS.charAt(index));
        }

        return captcha.toString();
    }

    /**
     * 生成验证码图片（Base64格式）
     * @param captchaText 验证码文本
     * @return Base64编码的图片字符串
     */
    public static String generateCaptchaImage(String captchaText) {
        try {
            // 创建图片对象
            BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = image.createGraphics();

            // 设置抗锯齿
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // 设置背景色为白色
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);

            // 绘制边框
            g2d.setColor(Color.GRAY);
            g2d.drawRect(0, 0, IMAGE_WIDTH - 1, IMAGE_HEIGHT - 1);

            // 绘制干扰线
            drawInterferenceLines(g2d);

            // 绘制验证码文字
            drawCaptchaText(g2d, captchaText);

            // 添加噪点
            drawNoisePoints(g2d);

            g2d.dispose();

            // 转换为Base64字符串
            return imageToBase64(image);

        } catch (Exception e) {
            throw new RuntimeException("生成验证码图片失败", e);
        }
    }

    /**
     * 绘制干扰线
     * @param g2d 图形对象
     */
    private static void drawInterferenceLines(Graphics2D g2d) {
        Random random = new Random();
        
        for (int i = 0; i < INTERFERENCE_LINE_COUNT; i++) {
            // 随机生成线条颜色
            int red = random.nextInt(150);
            int green = random.nextInt(150);
            int blue = random.nextInt(150);
            g2d.setColor(new Color(red, green, blue));
            
            // 随机生成线条坐标
            int x1 = random.nextInt(IMAGE_WIDTH);
            int y1 = random.nextInt(IMAGE_HEIGHT);
            int x2 = random.nextInt(IMAGE_WIDTH);
            int y2 = random.nextInt(IMAGE_HEIGHT);
            
            g2d.drawLine(x1, y1, x2, y2);
        }
    }

    /**
     * 绘制验证码文字
     * @param g2d 图形对象
     * @param captchaText 验证码文本
     */
    private static void drawCaptchaText(Graphics2D g2d, String captchaText) {
        Random random = new Random();
        
        // 字体大小
        int fontSize = 20;
        
        // 计算字符间距
        int charWidth = IMAGE_WIDTH / CAPTCHA_LENGTH;
        
        for (int i = 0; i < captchaText.length(); i++) {
            char c = captchaText.charAt(i);
            
            // 随机生成字体颜色（深色）
            int red = random.nextInt(100);
            int green = random.nextInt(100);
            int blue = random.nextInt(100);
            g2d.setColor(new Color(red, green, blue));
            
            // 随机生成字体样式
            String[] fontNames = {"Arial", "Georgia", "Times New Roman"};
            String fontName = fontNames[random.nextInt(fontNames.length)];
            int fontStyle = random.nextBoolean() ? Font.BOLD : Font.PLAIN;
            
            // 设置字体
            Font font = new Font(fontName, fontStyle, fontSize);
            g2d.setFont(font);
            
            // 计算字符位置（稍微随机偏移）
            int x = i * charWidth + random.nextInt(5) + 5;
            int y = IMAGE_HEIGHT / 2 + fontSize / 2 + random.nextInt(6) - 3;
            
            // 随机旋转角度（-15到15度）
            double angle = (random.nextDouble() - 0.5) * 30 * Math.PI / 180;
            g2d.rotate(angle, x, y);
            
            // 绘制字符
            g2d.drawString(String.valueOf(c), x, y);
            
            // 恢复旋转
            g2d.rotate(-angle, x, y);
        }
    }

    /**
     * 添加噪点
     * @param g2d 图形对象
     */
    private static void drawNoisePoints(Graphics2D g2d) {
        Random random = new Random();
        
        for (int i = 0; i < NOISE_POINT_COUNT; i++) {
            // 随机生成噪点颜色
            int red = random.nextInt(255);
            int green = random.nextInt(255);
            int blue = random.nextInt(255);
            g2d.setColor(new Color(red, green, blue));
            
            // 随机生成噪点位置
            int x = random.nextInt(IMAGE_WIDTH);
            int y = random.nextInt(IMAGE_HEIGHT);
            
            // 绘制噪点
            g2d.fillOval(x, y, 1, 1);
        }
    }

    /**
     * 将BufferedImage转换为Base64字符串
     * @param image 图片对象
     * @return Base64编码的图片字符串
     */
    private static String imageToBase64(BufferedImage image) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        byte[] imageBytes = baos.toByteArray();
        return Base64.getEncoder().encodeToString(imageBytes);
    }
}
